/*
MIT License

Copyright (c) 2021 Huawei Device Co., Ltd.

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
*/

import router from '@system.router';

const WATERMARK_FONT = '@we-cropper'

export default {
    props: {
        cropperOpt: {
            id: {
                default: 'cropper'
            },
            targetId: {
                default: 'targetCropper'
            },
            pixelRatio: {
                default: 1
            },
            width: {
                default: 720
            },
            height: {
                default: 720
            },
            scale: {
                default: 2.5
            },
            zoom: {
                default: 5
            },
            src: {
                default: ''
            },
            cut: {
                default: null
            },
            boundStyle: {
                default: null
            },
            onReady: {
                default: null
            },
            onBeforeImageLoad: {
                default: null
            },
            onImageLoad: {
                default: null
            },
            onBeforeDraw: {
                default: null
            },
        }
    },
    data: {
        isShow: false,
        rectX: 0,
        rectY: 0,
        baseWidth: 0,
        baseHeight: 0,
        imgLeft: 0,
        imgTop: 0,
        scaleWidth: 0,
        scaleHeight: 0,
        oldScale: 1,
        newScale: 1,
        oldDistance: 0,
        croperTarget: null, //image对象
        ctx: null,
        width: 300,
        height: 300,
        flag: 0, //处理返回界面后图片显示异常问题
        pr: 1 //pixelRatio
    },

    onInit() {
        this.pr = Number(this.cropperOpt.pixelRatio)
        this.isShow = this.cropperOpt.cut != undefined
        if (this.croperTarget == null) {
            this.croperTarget = new Image()
        }
        this.flag = 1

    },
    onPageShow() {
        if (this.flag == 1) {
            this.ctx = this.$element(this.cropperOpt.id).getContext('2d');
            this.width = Number(this.cropperOpt.width) / this.pr
            this.height = Number(this.cropperOpt.height) / this.pr
            if (typeof this.cropperOpt.src !== 'undefined') {
                this.pushOrign(this.cropperOpt.src)
            }
            if (typeof this.cropperOpt.boundStyle !== 'undefined') {
                // @ts-ignore
                this.setBoundStyle(this.cropperOpt.boundStyle)
            }
        }


    },


    //加载图片
    pushOrign(imageSrc) {
        let self = this
        this.croperTarget.src = imageSrc;
        this.croperTarget.onload = () => {
            //获取原始图片信息宽高
            let value = {
                size: {
                    width: self.croperTarget.width,
                    height: self.croperTarget.height
                }
            }
            //计算默认图片显示位置及区域
            self.getArgs(value)
            //canvas显示图片
            let width = self.scaleWidth / self.pr
            let height = self.scaleHeight / self.pr
            let dx = self.imgLeft / self.pr
            let dy = self.imgTop / self.pr
            self.ctx.drawImage(self.croperTarget, dx, dy, width, height);
            //canvas绘制透明层及裁剪框
            if (typeof self.cropperOpt.boundStyle !== 'undefined') {
                // @ts-ignore
                self.setBoundStyle(self.cropperOpt.boundStyle)
            }


            this.cropperOpt.src = imageSrc
        };
        this.croperTarget.onerror = () => {
            console.log('Image load fail');
        };


    },
    //移除图片
    removeImage() {
        this.ctx.clearRect(0, 0, this.cropperOpt.width, this.cropperOpt.height)
        this.cropperOpt.src = null
    },
    //裁剪图片
    getCropperImage() {
        if (this.isShow) {
            let targetCtx = this.$element(this.cropperOpt.targetId).getContext('2d');
            let ddx = (this.imgLeft - this.cropperOpt.cut.x) / Number(this.cropperOpt.pixelRatio)
            let ddy = (this.imgTop - this.cropperOpt.cut.y) / Number(this.cropperOpt.pixelRatio)
            let width = this.scaleWidth / Number(this.cropperOpt.pixelRatio)
            let height = this.scaleHeight / Number(this.cropperOpt.pixelRatio)
            targetCtx.drawImage(this.croperTarget, ddx, ddy, width, height)
        }

        if (this.cropperOpt.onBeforeDraw !== null && this.cropperOpt.onBeforeDraw !== undefined) {
            this.ctx.font = '14px sans-serif';
            this.ctx.fillStyle = '#ffffff'
            this.ctx.fillText(WATERMARK_FONT, 450, 450)
        }
        let dataURL = typeof this.cropperOpt.cut !== 'undefined' ? this.$element(this.cropperOpt.targetId).toDataURL() : this.$element(this.cropperOpt.id).toDataURL()
        this.flag = 0
        router.push({
            uri: "pages/previewImage/previewImage",
            params: {
                imageSrc: dataURL,
            }
        })

    },


    //处理触摸开始事件
    touchStart(e) {
        let [touch0, touch1] = e.touches
        if (!this.cropperOpt.src) return
        // 计算第一个触摸点的位置，并参照改点进行缩放
        this.__oneTouchStart(touch0)
        // 两指手势触发
        if (e.touches.length >= 2) {
            this.__twoTouchStart(touch0, touch1)
        }

    },
    //处理触摸移动事件
    touchMove(e) {
        let [touch0, touch1] = e.touches
        if (!this.cropperOpt.src) return
        // 单指手势时触发
        if (e.touches.length === 1) {
            this.__oneTouchMove(touch0)
        }
        // 两指手势触发
        if (e.touches.length >= 2) {
            this.__twoTouchMove(touch0, touch1)
        }
    },
    //处理触摸结束事件
    touchEnd(e) {
        if (!this.cropperOpt.src) {
            return
        }
        this.__xtouchEnd();
    },


    //绘制裁剪层
    setBoundStyle({ color = '#04b00f', mask = 'rgba(0, 0, 0, 0.3)', lineWidth = 1 } = {}) {
        let boundWidth = this.cropperOpt.width // 裁剪框默认宽度，即整个画布宽度
        let boundHeight = this.cropperOpt.height
        // 裁剪框默认高度，即整个画布高度
        let { x = 0, y = 0, width = boundWidth, height = boundHeight } = this.cropperOpt.cut
        let half = lineWidth / 2
        //PX2VP
        let dx = x / this.pr
        let dy = y / this.pr
        let dwidth = width / this.pr
        let dheight = height / this.pr
        let dboundWidth = Number(boundWidth) / this.pr
        let dboundHeight = Number(boundHeight) / this.pr
        let boundOption = [
            {
                start: {
                    x: dx - half, y: dy + 10 - half
                },
                step1: {
                    x: dx - half, y: dy - half
                },
                step2: {
                    x: dx + 10 - half, y: dy - half
                }
            },
            {
                start: {
                    x: dx - half, y: dy + dheight - 10 + half
                },
                step1: {
                    x: dx - half, y: dy + dheight + half
                },
                step2: {
                    x: dx + 10 - half, y: dy + dheight + half
                }
            },
            {
                start: {
                    x: dx + dwidth - 10 + half, y: dy - half
                },
                step1: {
                    x: dx + dwidth + half, y: dy - half
                },
                step2: {
                    x: dx + dwidth + half, y: dy + 10 - half
                }
            },
            {
                start: {
                    x: dx + dwidth + half, y: dy + dheight - 10 + half
                },
                step1: {
                    x: dx + dwidth + half, y: dy + dheight + half
                },
                step2: {
                    x: dx + dwidth - 10 + half, y: dy + dheight + half
                }
            }
        ]
        // 绘制半透明层
        this.ctx.fillStyle = mask
        this.ctx.fillRect(0, 0, dx, dboundHeight)
        this.ctx.fillRect(dx, 0, dwidth, dy)
        this.ctx.fillRect(dx, dy + dheight, dwidth, dboundHeight - dy - dheight + 1)
        this.ctx.fillRect(dx + dwidth, 0, dboundWidth - dx - dwidth + 1, dboundHeight)
        boundOption.forEach(op => {
            this.ctx.beginPath()
            this.ctx.strokeStyle = color
            this.ctx.lineWidth = lineWidth
            this.ctx.moveTo(op.start.x, op.start.y)
            this.ctx.lineTo(op.step1.x, op.step1.y)
            this.ctx.lineTo(op.step2.x, op.step2.y)
            this.ctx.stroke()
        })

    },
    //计算图片默认显示位置
    getArgs(res) {
        let self = this
        let {
            x = 0,
            y = 0,
            width = 0,
            height = 0
        } = typeof self.cropperOpt.cut !== 'undefined' ? self.cropperOpt.cut : self.cropperOpt
        let innerAspectRadio = res.size.width / res.size.height
        let customAspectRadio = Number(width) / Number(height)
        if (innerAspectRadio < customAspectRadio) {
            self.rectX = x
            self.baseWidth = Number(width)
            self.baseHeight = Number(width) / innerAspectRadio
            self.rectY = y - Math.abs((Number(height) - Number(self.baseHeight)) / 2)
        } else {
            self.rectY = y
            self.baseWidth = Number(height) * innerAspectRadio
            self.baseHeight = Number(height)
            self.rectX = x - Math.abs((Number(width) - Number(self.baseWidth)) / 2)
        }
        self.imgLeft = self.rectX
        self.imgTop = self.rectY
        self.scaleWidth = self.baseWidth
        self.scaleHeight = self.baseHeight
    },
    //更新canvas
    updateCanvas() {
        if (this.croperTarget != null) {
            //  画布绘制图片
            let dx = this.imgLeft / this.pr
            let dy = this.imgTop / this.pr
            let width = this.scaleWidth / this.pr
            let height = this.scaleHeight / this.pr
            this.ctx.drawImage(
                this.croperTarget,
                dx,
                dy,
                width,
                height
            )
            if (typeof this.cropperOpt.boundStyle !== 'undefined') {
                // @ts-ignore
                this.setBoundStyle(this.cropperOpt.boundStyle)
            }

        }
    },
    //获取最新缩放系数
    getNewScale(oldScale, oldDistance, zoom, touch0, touch1) {
        let xMove, yMove, newDistance
        // 计算二指最新距离
        xMove = Math.round(touch1.localX - touch0.localX)*this.pr
        yMove = Math.round(touch1.localY - touch0.localY)*this.pr
        newDistance = Math.round(Math.sqrt(xMove * xMove + yMove * yMove))
        return oldScale + 0.001 * zoom * (newDistance - oldDistance)
    },
    //单指触摸开始事件
    __oneTouchStart(touch) {
        this.touchX0 = Math.round(touch.localX)*this.pr
        this.touchY0 = Math.round(touch.localY)*this.pr
    },
    //单指触摸移动事件
    __oneTouchMove(touch) {
        let xMove, yMove
        xMove = Math.round(touch.localX - this.touchX0) * this.pr
        yMove = Math.round(touch.localY - this.touchY0) * this.pr
        let imgLeft = Math.round(this.rectX + xMove)
        let imgTop = Math.round(this.rectY + yMove)
        this.outsideBound(imgLeft, imgTop)
        this.updateCanvas()
    },
    //单指触摸结束事件
    __xtouchEnd() {
        this.oldScale = this.newScale
        this.rectX = this.imgLeft
        this.rectY = this.imgTop
    },
    //双指触摸开始事件
    __twoTouchStart(touch0, touch1) {
        let xMove, yMove, oldDistance
        this.touchX1 = Math.round(this.rectX + this.scaleWidth / 2)
        this.touchY1 = Math.round(this.rectY + this.scaleHeight / 2)
        // 计算两指距离
        xMove = Math.round(touch1.localX - touch0.localX) * this.pr
        yMove = Math.round(touch1.localY - touch0.localY) * this.pr
        oldDistance = Math.round(Math.sqrt(xMove * xMove + yMove * yMove))
        this.oldDistance = oldDistance
    },
    //双指触摸移动事件
    __twoTouchMove(touch0, touch1) {
        let { oldScale, oldDistance } = this
        let {scale, zoom} = this.cropperOpt
        this.newScale = this.getNewScale(oldScale, oldDistance, zoom, touch0, touch1)
        //  设定缩放范围
        if(this.newScale <= 1){
            this.newScale = 1
        }

        if(this.newScale >= scale){
            this.newScale = scale
        }
        this.scaleWidth = Math.round(this.newScale * this.baseWidth)
        this.scaleHeight = Math.round(this.newScale * this.baseHeight)
        let imgLeft = Math.round(this.touchX1 - this.scaleWidth / 2)
        let imgTop = Math.round(this.touchY1 - this.scaleHeight / 2)
        this.outsideBound(imgLeft, imgTop)
        this.updateCanvas()
    },
    //计算滑动边界值
    outsideBound(imgLeft, imgTop) {
        let {
            x = 0,
            y = 0,
            width = 0,
            height = 0
        } = typeof this.cropperOpt.cut !== 'undefined' ? this.cropperOpt.cut : this.cropperOpt
        this.imgLeft = imgLeft >= x
            ? x
            : this.scaleWidth + imgLeft - x <= width
                  ? x + width - this.scaleWidth
                  : imgLeft
        this.imgTop = imgTop >= y
            ? y
            : this.scaleHeight + imgTop - y <= height
                  ? y + height - this.scaleHeight
                  : imgTop
    }
}
